{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 变量作用域\n",
    "- global:全局变量\n",
    "- local:局部变量\n",
    "- 在函数中定义全局变量：在变量名前加上global\n",
    "- locals()函数是打印所有定义的局部变量，globals（）是。。。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Local:{'d': 4, 'c': 3}\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "a=1\n",
    "b=2\n",
    "def func(c,d):\n",
    "    global e\n",
    "    e=5\n",
    "    print(\"Local:{}\".format(locals()))\n",
    "func(3,4)\n",
    "#e已经被定义成了一个全局变量\n",
    "print(e)\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 把字符串当作代码执行的函数\n",
    "- eval()：具有返回值\n",
    "- exec()：不具有返回值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5+6\n",
      "11\n"
     ]
    }
   ],
   "source": [
    "print(\"5+6\")\n",
    "print(eval(\"5+6\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 递归函数\n",
    "- 函数直接或者间接调用函数本身\n",
    "- 递归具有递归深度，次数太多就会报错"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "'break' outside loop (<ipython-input-2-4875362af16a>, line 7)",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-2-4875362af16a>\"\u001b[1;36m, line \u001b[1;32m7\u001b[0m\n\u001b[1;33m    break\u001b[0m\n\u001b[1;37m    ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m 'break' outside loop\n"
     ],
     "output_type": "error"
    }
   ],
   "source": [
    "x=0\n",
    "def func():\n",
    "    global x\n",
    "    print(x)\n",
    "    x+=1\n",
    "        \n",
    "func()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### f(n)=f(n-1)+f(n-2)的递归实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def func(n):\n",
    "    if n==1:\n",
    "        return 1\n",
    "    if n==2:\n",
    "        return 2\n",
    "    return func(n-1)+func(n-2)\n",
    "func(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 列表list\n",
    "- 定义：var=[2,3,4]或者var=list([2,3,4])\n",
    "- 取出列表内容使用数组相似操作，var['index']\n",
    "- 切片 var[1,4]:取出列表var的值，包括var['1'],2和3\n",
    "- 相应的函数操作\n",
    "    - list.append(x):插入一个元素\n",
    "    - len(list):统计list的元素个数\n",
    "    - list.sort():列表排序\n",
    "    - list.remove(value):移除列表中的value的第一个匹配项\n",
    "    - list.pop():移除列表的最后一个元素\n",
    "    - del(list['index']):删除一个元素\n",
    "    - list(内容):将内容转化成list类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 3, 4]\n",
      "[2, 3, 4, 2]\n",
      "[2, 3, 4]\n",
      "[2, 4]\n",
      "[2, 4, 2, 4]\n",
      "[2, 2, 4, 4]\n",
      "[2, 2]\n",
      "['i', ' ', 'a', 'm', ' ', 'p', 'o', 'w', 'e', 'r', '!']\n"
     ]
    }
   ],
   "source": [
    "var=list([2,3,4])\n",
    "print(var)\n",
    "var.append(2)\n",
    "print(var)\n",
    "var.pop()\n",
    "print(var)\n",
    "del(var[1])\n",
    "print(var)\n",
    "var.append(2)\n",
    "var.append(4)\n",
    "print(var)\n",
    "var.sort()\n",
    "print(var)\n",
    "while 4 in var:\n",
    "    var.remove(4)\n",
    "print(var)\n",
    "\n",
    "print(list(\"i am power!\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 汉诺塔问题的代码实现\n",
    "- 规则：\n",
    "    - 一次只能一定一个盘子\n",
    "    - 大盘子不能够压在小盘子上面\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A --> C\n",
      "A --> B\n",
      "C --> B\n",
      "A --> C\n",
      "B --> A\n",
      "B --> C\n",
      "A --> C\n"
     ]
    }
   ],
   "source": [
    "def func(n,a,b,c):\n",
    "    '''\n",
    "    n:代表一共有n个盘子\n",
    "    a:代表第一个塔\n",
    "    b:第二个塔\n",
    "    c:第三个塔\n",
    "    '''\n",
    "    if n==1:\n",
    "        print(a,'-->',c)\n",
    "        return \n",
    "    if n==2:\n",
    "        print(a,'-->',b)\n",
    "        print(a,'-->',c)\n",
    "        print(b,'-->',c)\n",
    "        return \n",
    "    # 把A上的盘子借助C移动到B上去\n",
    "    func(n-1,a,c,b)\n",
    "    # 把A上的最大盘子移动到C盘上去\n",
    "    print(a,'-->',c)\n",
    "    # 把B上的盘子借助A盘移动到C盘上去\n",
    "    func(n-1,b,a,c)\n",
    "func(3,'A','B','C')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 双层遍历\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "power\n",
      "12\n",
      "13\n",
      "lsl\n",
      "python\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "var = ['power',[12,13],['lsl','python',1]]\n",
    "for i in var:\n",
    "    if type(i)==list:\n",
    "        for j in i:\n",
    "            print(j)\n",
    "    else:\n",
    "        print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 传值和传指的区别：数组在函数改变属于穿指，相当于完全改变了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'a' is not defined",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-5-f7e67f4fa48c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      2\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      3\u001b[0m \u001b[1;32mdel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      5\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mb\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mclear\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'a' is not defined"
     ],
     "output_type": "error"
    }
   ],
   "source": [
    "a= [1,2,3]\n",
    "b= [1,2,3]\n",
    "del(a)\n",
    "print(a)\n",
    "print(b.clear())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 拷贝和浅拷贝的区别：\n",
    "- a=b相当于让a和b当时指向一个单元。a=b.copy()不是指向同一单元的相同值。\n",
    "- 只是适用于列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 2]\n",
      "[2, 2]\n"
     ]
    }
   ],
   "source": [
    "a=[1,2]\n",
    "b=a\n",
    "a[0]=2\n",
    "print(a)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 元组（tuple）\n",
    "- 元组相当于就是没有修改操作的列表\n",
    "- 列表的所有操作元组都有"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 2, 3, 4)\n",
      "(2, 4)\n",
      "(1, 2, 3, 4, 5, 6)\n"
     ]
    }
   ],
   "source": [
    "a=[1,2,3,4]\n",
    "a=tuple(a)\n",
    "print(a)\n",
    "# 打印出a【0】到元祖的最后的最后一个字符且step==2\n",
    "print(a[1::2])\n",
    "# 这个是相当于赋值操作而不是一个修稿操作\n",
    "a+=(5,6)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 集合（set）\n",
    "- 不存在重复的元素，如果有，自动过滤\n",
    "- 集合不存在索引和切片。因为他是用hash存储的内容"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3}\n",
      "{1, 2, 3, 4}\n",
      "{1, 2, 3}\n",
      "{1, 2, 3}\n"
     ]
    }
   ],
   "source": [
    "a={1,1,2,2,3,3}\n",
    "print(a)\n",
    "a.add(4)    # 和append 的区别是他只是插入而不是末尾插入，因为他没有索引\n",
    "print(a)\n",
    "a.remove(4)\n",
    "print(a)\n",
    "a.discard(4)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 集合的交并差以及子集父集\n",
    "- a.intersection():交集   a&b\n",
    "- a.difference():差集  a-b也是表示差集\n",
    "- a.union():并集     a|b\n",
    "- a.issubset():子集    a<b\n",
    "- a.issuberset():父集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{3, 4}\n",
      "set()\n",
      "{3, 4, 5, 6}\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "a={3,4}\n",
    "b={3,4,5,6}\n",
    "print(a&b)\n",
    "print(a-b)\n",
    "print(a|b)\n",
    "print(a<b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 字典（dict）\n",
    "- 字典是由许多key-value对组成的\n",
    "- 字典的key是由hash存储的，所以不能用索引和切片\n",
    "- 字典常用函数：\n",
    "    - dict.keys():所有key组成的列表\n",
    "    - dict.values():所有value组成的列表\n",
    "    - dict.items():相当于key，value组成的二元数组\n",
    "    - dict.get('key',默认值)：get方法可以取出字典中相应的值，且可以指定默认值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "key\n",
      "one --> 1\n",
      "two --> 2\n",
      "three --> 3\n",
      "4\n",
      "{'one': 1, 'three': 3}\n"
     ]
    }
   ],
   "source": [
    "a ={\"one\":1,\"two\":2,\"three\":3}\n",
    "if \"one\" in a:    # 这里检测的是key是否在字典中\n",
    "    print('key')\n",
    "# 字典遍历\n",
    "for k,v in a.items():\n",
    "    print(k,'-->',v)\n",
    "print(a.get('four',4))\n",
    "b={k:v for k,v in a.items() if v%2}\n",
    "print(b)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
